package com.ebelter.btlibrary.btble.impl.buc;


import com.ebelter.btlibrary.btble.ble.bluetooth.device.impl.BleMessageAnalyser;
import com.ebelter.btlibrary.btble.ble.bluetooth.device.impl.Channel;
import com.ebelter.btlibrary.btble.impl.buc.callback.BucError;
import com.ebelter.btlibrary.btble.impl.buc.callback.BucResultCallback;
import com.ebelter.btlibrary.btble.impl.buc.model.BucCommand;
import com.ebelter.btlibrary.btble.impl.buc.model.CholResult;
import com.ebelter.btlibrary.btble.impl.buc.model.GluResult;
import com.ebelter.btlibrary.btble.impl.buc.model.UaResult;
import com.ebelter.btlibrary.btble.impl.ecg.callback.EcgResultCallback;
import com.ebelter.btlibrary.btble.impl.ecg.model.EcgResult;
import com.ebelter.btlibrary.util.ULog;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 血糖/尿酸/胆固醇分析仪数据解析器
 * Created by Sergio Pan on 2017/12/8.
 */

public class BucMessageAnalyser extends BleMessageAnalyser {

    private static final String TAG = "BucMessageAnalyser";

    private static BucMessageAnalyser instance = new BucMessageAnalyser();

    //数据解析后的各种回调
    private BucResultCallback measureResultCallback;

    private int tag;
    private long preMeasureTime;

    private BucMessageAnalyser() {
//        recordSet.
    }

    public static BucMessageAnalyser getInstance() {
        return instance;
    }


    public void registerMeasureResultCallback(BucResultCallback callback) {
        this.measureResultCallback = callback;
    }


    /**
     * 解密数据
     *
     * @param data
     * @return
     */
    @Override
    protected byte[] decrypt(byte[] data) {
//        ULog.i(TAG, "-------decrypt--------data = " + getArrayString(data));
        //TODO 如若是加密数据，在此做解密处理,如若非加密数据，可不重写此方法

        return data;
    }

    /**
     * 开始解析
     *
     * @param data
     * @return
     */
    @Override
    protected void analyze(Channel channel, byte[] data) {
        ULog.i(TAG, "-------analyze----before filter----data = " + getArrayString(data));
        //解密后
//        if (data.length < 2 || data[0] != dataHeaderReceive || data.length != (data[1] & 0xff) + 3) {
//            return;
//        }
//        ULog.i(TAG, "-------analyze---after filter-----data = " + getArrayString(data));
        //业务码
        tag++;
        if (tag == 3) {//3条为一组数据
            tag = 0;
        }
        if (tag == 1) {//数据开始标记
            return;
        }

        if ((data[0] & 0xff) == 0x55) {
            tag = 0;
            mInternalChannel.sendCommnd(BucCommand.RECEIVEE);
            return;
        }


        int cmdCode = (data[1] & 0xff) >> 6;
        ULog.i(TAG, "-------handlerData--------cmdCode = " + Integer.toHexString(cmdCode));
        switch (cmdCode) {

            case 0x01: //血糖测量结果
                doGluResult(data);
                break;
            case 0x02: //尿酸测量结果
                doUaResults(data);
                break;
            case 0x03: //胆固醇测量结果
                doCholResult(data);
                break;
            case 0x5a: //Lo 过低
                doError(BucError.TOO_LOW);
                break;
            case 0xa5: //Hi 过高
                doError(BucError.TOO_HIGH);
                break;

        }


    }


    /**
     * 收到血糖测量结果
     *
     * @param data
     */
    private void doGluResult(byte[] data) {

        int temp = data[1] & 0x3f;
        int glu = (temp << 8) | data[2];
        int year = data[3] & 0xff;
        int month = data[4] & 0xff;
        int day = data[5] & 0xff;
        int hour = data[6] & 0xff;
        int minute = data[7] & 0xff;
        int sec = data[8] & 0xff;

        year += 2000;
        Date measureDate = new Date(year - 1900, month - 1, day, hour, minute, sec);
        long measureTime = measureDate.getTime();
        if (preMeasureTime >= measureTime) {
            return;
        }
        ULog.i(TAG, "-----doGluResult------receive measure result. glu = " + glu + ", year = " + year);
        GluResult result = new GluResult();


        result.setMeasureTime(measureTime);
        result.setMeasureTimeStr(getMeasureTimeStr(measureTime));
        result.setGlu(glu / 10.0f);


        if (measureResultCallback != null) {
            measureResultCallback.onReceiveGluResult(result);
        }

        preMeasureTime = measureTime;
    }

    /**
     * 收到尿酸测量结果
     *
     * @param data
     */
    private void doUaResults(byte[] data) {

        int temp = data[1] & 0x3f;
        int ua = (temp << 8) | data[2];

        int year = data[3] & 0xff;
        int month = data[4] & 0xff;
        int day = data[5] & 0xff;
        int hour = data[6] & 0xff;
        int minute = data[7] & 0xff;
        int sec = data[8] & 0xff;

        year += 2000;
        Date measureDate = new Date(year - 1900, month - 1, day, hour, minute, sec);
        long measureTime = measureDate.getTime();
        if (preMeasureTime >= measureTime) {
            return;
        }
        ULog.i(TAG, "-----doUaResults------receive measure result. ua = " + ua + ", year = " + year);

        UaResult result = new UaResult();


        result.setMeasureTime(measureTime);
        result.setMeasureTimeStr(getMeasureTimeStr(measureTime));
        result.setUa(ua);

        if (measureResultCallback != null) {
            measureResultCallback.onReceiveUaResult(result);
        }
        preMeasureTime = measureTime;
    }

    /**
     * 收到胆固醇测量结果
     *
     * @param data
     */
    private void doCholResult(byte[] data) {

        int temp = data[1] & 0x3f;
        int chol = (temp << 8) | data[2];


        int year = data[3] & 0xff;
        int month = data[4] & 0xff;
        int day = data[5] & 0xff;
        int hour = data[6] & 0xff;
        int minute = data[7] & 0xff;
        int sec = data[8] & 0xff;

        year += 2000;
        Date measureDate = new Date(year - 1900, month - 1, day, hour, minute, sec);
        long measureTime = measureDate.getTime();
        if (preMeasureTime >= measureTime) {
            return;
        }
        ULog.i(TAG, "-----doUaResults------receive measure result. chol = " + chol + ", year = " + year);

        CholResult result = new CholResult();
        result.setMeasureTime(measureTime);
        result.setMeasureTimeStr(getMeasureTimeStr(measureTime));
        result.setChol(chol / 100.0f);

        if (measureResultCallback != null) {
            measureResultCallback.onReceiveCholResult(result);
        }
        preMeasureTime = measureTime;
    }

    /**
     * 错误码
     * @param error
     */
    private void doError(BucError error) {
        if (measureResultCallback != null) {
            measureResultCallback.onError(error);
        }
    }


    private List<Integer> getAdcResult(byte[] data) {
        List<Integer> results = new ArrayList<>();
        int cycle = getMultCycle(8, 12);
        int count = (data.length - 2) / cycle;
        if ((data.length - 2) % cycle != 0) {
            count += 1;
        }
        for (int i = 2; i < count; i++) {
            int temp2 = data[i * cycle + 1];
            int result0 = data[i * cycle] << 4 + temp2 >> 4;
            int result1 = data[i * cycle + 1] << 8 + data[i * cycle + 2];
            results.add(result0);
            results.add(result1);
        }
        return results;
    }

    /**
     * 获取a位转b位的周期
     *
     * @param a
     * @param b
     * @return
     */
    private int getMultCycle(int a, int b) {
        int aa = a;
        int bb = b;
        int m = aa % bb;
        while (m != 0) {
            aa = bb;
            bb = m;
            m = aa % bb;
        }
        return (a * b / bb) / Math.min(a, b);
    }


    public int getDecryptValue(byte a, byte b) {
        int aa = a & 0xff;
        int bb = b & 0xff;
        return (bb << 8) | aa;
    }


    @Override
    public void onRelease() {
        super.onRelease();


    }
}
